#!/usr/bin/env python
#-*- encoding: utf-8 -*-

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from base64 import b64encode
import setproctitle
import tornado.ioloop
import tornado.web
import threading
import smtplib
import json


PORT = 7000


setproctitle.setproctitle('asp-mail')


def send_email(mail_info):
    smtp = None

    try:
        encoding = 'utf-8'
        email = MIMEMultipart()

        if mail_info['from_name'] != '':
            email['from'] =  '=?%s?B?%s?=' % (encoding, b64encode(mail_info['from_name'].encode('utf-8'))) + ' <' + mail_info['from'] + '>'
        else:
            email['from'] = mail_info['from']

        email['to'] = mail_info['to']
        email['subject'] = '=?%s?B?%s?=' % (encoding, b64encode(mail_info['subject'].encode('utf-8')))

        if mail_info['is_html']:
            subtype = 'html'
        else:
            subtype = 'plain'

        email.attach(MIMEText(mail_info['body'], subtype, _charset=encoding))

        if 'port' in mail_info:
            server_args = (mail_info['host'], mail_info['port'])
        else:
            server_args = (mail_info['host'], )

        if mail_info['secure'] != '':
            smtp = smtplib.SMTP_SSL(*server_args)

            smtp.ehlo()
            if email['secure'] == 'tls':
                smtp.starttls()
                smtp.ehlo()
        else:
            smtp = smtplib.SMTP(*server_args)
            smtp.ehlo()

        if mail_info['is_auth']:
            smtp.login(mail_info['username'], mail_info['password'])  

        smtp.sendmail(mail_info['from'], mail_info['to'], email.as_string())
        smtp.quit()
    except Exception, e:
        if smtp:
            smtp.quit()


class SendEmailThread(threading.Thread):

    def __init__(self, email):
        self.email = email
        threading.Thread.__init__(self)
        threading.daemon = True

    def run(self):
        send_email(self.email)


def web_hint_message(status = 'success', message = '', data = {}):
    o = data
    o['status'] = status
    o['message'] = message
    return json.dumps(o)


class SendEmailHandler(tornado.web.RequestHandler):
    def post(self):
        self.set_header("Content-Type", "application/json")
        
        try:
            email = self.get_argument('email')

            email = json.loads(email)
            if not isinstance(email, dict):
                raise Exception('a')

            keys = [ 'host', 'is_auth', 'secure', 'username', 'password', 'from_name', 'from', 'to', 'subject', 'body', 'is_html' ]
            for x in keys:
                if x not in email:
                    self.write(web_hint_message('error', 'missing %s' % x))
                    return

            if 'port' in email:
                email['port'] = int(email['port'])

            email['is_auth'] = (email['is_auth'] == '1')
            
            email_thr = SendEmailThread(email)
            email_thr.start()
        except Exception, e:
            self.write(web_hint_message('error', u'无效的参数！'))
            return

        self.write(web_hint_message())


application = tornado.web.Application([
    (r"/send_email", SendEmailHandler),
])


if __name__ == "__main__":
    application.listen(PORT)
    tornado.ioloop.IOLoop.instance().start()

